/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package br.ufrgs.inf.inf05005.main;

import br.ufrgs.inf.inf05005.automatos.AutomNode;
import br.ufrgs.inf.inf05005.automatos.Automato;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.BufferedReader;
import java.io.File;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.Iterator;
import javax.swing.JButton;
import javax.swing.JFileChooser;
import net.fkrahe.graph.WLinkedGraph;

/**
 *
 * @author fkrahe
 */
public class Main implements ActionListener {

    private JButton jbutton;
    private WLinkedGraph graph;

    /**
     * @param args the command line arguments
     */
    public static void main(String[] args) {
        Main gui = new Main();
        gui.show();
    }

    /**
     * Instantiates buttons, frames, file choosers...
     */
    public void show() {
//        if (Utils.DEBUG) {
        BufferedReader bufferedeReader = new BufferedReader(new InputStreamReader(System.in));
        String fileName = null;
        try {// /Users/fkrahe/Desktop/basquete3.txt
            System.out.println("Entre o nome do arquivo, com caminho: ");
            while ((fileName = bufferedeReader.readLine()) == null || fileName.length() == 0) {
                System.out.println("Digite corretamente, por favor.");
            }
        } catch (IOException ex) {
            System.out.println("Exceção: " + ex.getMessage());
        }
        File file = new File(fileName);
        try {
            // Cria o automato a partir do arquivo
            Automato afd = new Automato(file);
            graphPrepare(afd);
            System.out.println("Digite E para ver a expressão regular; A para avaliar uma palavra; S para sair.");
            String command = null;
            while (!(command = bufferedeReader.readLine()).equals("S")) {
                if(command.equals("E")){
                    System.out.println(graph.getER());
                } else if(command.equals("A")){
                    System.out.println("Digite a palavra para avalição: ");
                    String palavra = null;
                    while((palavra = bufferedeReader.readLine())==null){
                        System.out.println("Digite a palavra para avalição: ");
                    }
                    System.out.println(graph.readWord(palavra) ? "Aceita" : "Rejeita");
                }
                System.out.println("Digite E para ver a expressão regular; A para avaliar uma palavra; S para sair.");
            }

        } catch (Exception ex) {
            System.out.println("Main.show(): " + ex.getMessage());
            System.out.println("Main.show(): \n0 " + ex.getStackTrace()[0] + " \n1 " + ex.getStackTrace()[1] + " \n2 " + ex.getStackTrace()[2]);
        }
//        } else {
//            // Mostra interface gráfica
//            jbutton = new JButton(Utils.LABEL_BUTTON_LOAD_FILE);
//            JFrame jframe = new JFrame();
//            jframe.getContentPane().add(jbutton);
//            jframe.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
//            // sets listener
//            jbutton.addActionListener(this);
//            jframe.setSize(Utils.WINDOW_WIDTH, Utils.WINDOW_HEIGHT);
//            jframe.setVisible(true);
//        }
    }

    /**
     * Roda quando o botão de carregar arquivo é pressionado.
     * @param e - é o tipo do evento. Isso vem do botão.
     */
    @Override
    public void actionPerformed(ActionEvent e) {
        try {
            if (e.getSource() == jbutton) {
                JFileChooser fc = new JFileChooser();
                int returnVal = fc.showOpenDialog(jbutton);

                if (returnVal == JFileChooser.APPROVE_OPTION) {
                    graphPrepare(new Automato(fc.getSelectedFile()));
                } else {
                    throw new Exception("Valor de retorno do botão é desconhecido.");
                }
            }
        } catch (Exception ex) {
            System.out.println(ex.getMessage());
        }
    }

    private void graphPrepare(Automato afd) {
//        System.out.println("AFND: ");
//        Utils.printMatrix(afd.getTabelaDeTransicao());
        afd.determiniza();
//        System.out.println("AFD: ");
//        Utils.printMatrix(afd.getTabelaDeTransicao());
//        System.out.println("Novos estados do autômato: ");
//        System.out.println(afd.getEstados().toString());
//        System.out.println("Novos estados FINAIS do autômato: ");
//        System.out.println(afd.getEstadosFinais().toString());

        /**
         * afd is deterministic already
         * Let's build a graph
         */
        graph = new WLinkedGraph();
        ArrayList<String> estados = afd.getEstados();
        for (int i = 0; i < estados.size(); i++) {
            AutomNode node = new AutomNode(estados.get(i).replace(",", ""));
            if(node!=null)
            graph.add(node);
        }

        ArrayList<String> finais = afd.getEstadosFinais();
        for (int i = 0; i < finais.size(); i++) {
            String tmpState = finais.get(i).replace(",", "");
            AutomNode tmpNode = new AutomNode(tmpState, true);
            Iterator<AutomNode> itrNodes = graph.nodes();
            while (itrNodes.hasNext()) {
                AutomNode permNode = itrNodes.next();
                if (permNode.equals(tmpNode)) {
                    permNode.setIsFinal(true);
                }
            }
        }

        /**
         * Our Graph has all nodes from the output of afd.determiniza();
         * 
         * Now we want to connect the nodes
         */
        String[][] transTab = afd.getTabelaDeTransicao();
        String[] lico = transTab[0][0].split(",");
        int li = Integer.parseInt(lico[0]);
        int co = Integer.parseInt(lico[1]);
        for (int i = 1; i < li; i++) {
            for (int j = 1; j < co; j++) {
                if (transTab[i][j] != null && !"".equals(transTab[i][j])) {
                    AutomNode fixState = new AutomNode(transTab[i][0].replace(",", ""));
                    AutomNode varState = new AutomNode(transTab[i][j].replace(",", ""));
                    String weight = transTab[0][j];
                    graph.join(fixState, varState, weight);
                }
            }
        }
    }
}
